#include "inc/zg291pecu_para.h"
#include "ui_zg291pecu_para.h"

zg291pecu_para::zg291pecu_para(QSerialPort *serialPort,QTimer *m_timer,QWidget *parent) :
    QWidget(parent),
    ui(new Ui::zg291pecu_para),
    serialPort(serialPort),
    m_timer(m_timer)
{
    ui->setupUi(this);
}

zg291pecu_para::~zg291pecu_para()
{
    delete ui;
}

void zg291pecu_para::on_pushButton_clicked()
{
    // 停止定时器（如果有）
    if (m_timer && m_timer->isActive()) {
        m_timer->stop();
    }

    // 检查串口状态
    if (!serialPort || !serialPort->isOpen()) {
        qDebug() << "Serial port not ready!";
//        if (m_timer) m_timer->start(2000);
        return;
    }

    /**************** 第一条指令：读取0x47-0x50寄存器 (10个寄存器) ****************/
    QByteArray request1;
    request1.append(static_cast<char>(0x00));     // 从机地址
    request1.append(static_cast<char>(0x03));     // 功能码
    request1.append(static_cast<char>(0x00));     // 起始地址高字节
    request1.append(static_cast<char>(0x73));     // 起始地址低字节 (0x47)
    request1.append(static_cast<char>(0x00));     // 寄存器数高字节
    request1.append(static_cast<char>(0x0A));     // 寄存器数低字节 (10个寄存器)

    // 计算并附加CRC
    quint16 crc1 = calculateCRC(request1);
    request1.append(static_cast<char>(crc1 & 0xFF));
    request1.append(static_cast<char>((crc1 >> 8) & 0xFF));

    // 发送第一条指令
    if (serialPort->write(request1) == -1) {
        qDebug() << "Write failed (1):" << serialPort->errorString();
//        if (m_timer) m_timer->start(2000);
        return;
    }

    // 读取第一条响应
    QByteArray response1;
    if (serialPort->waitForReadyRead(1000)) {
        response1 = serialPort->readAll();
        while (serialPort->waitForReadyRead(100)) {
            response1 += serialPort->readAll();
        }
    } else {
        qDebug() << "Read timeout (1)";
//        if (m_timer) m_timer->start(2000);
        return;
    }

    /**************** 第二条指令：读取0x88-0x89寄存器 (2个寄存器) ****************/
    QByteArray request2;
    request2.append(static_cast<char>(0x00));     // 从机地址
    request2.append(static_cast<char>(0x03));     // 功能码
    request2.append(static_cast<char>(0x00));     // 起始地址高字节
    request2.append(static_cast<char>(0x90));     // 起始地址低字节 (0x88)
    request2.append(static_cast<char>(0x00));     // 寄存器数高字节
    request2.append(static_cast<char>(0x02));     // 寄存器数低字节 (2个寄存器)

    // 计算并附加CRC
    quint16 crc2 = calculateCRC(request2);
    request2.append(static_cast<char>(crc2 & 0xFF));
    request2.append(static_cast<char>((crc2 >> 8) & 0xFF));

    // 发送第二条指令
    if (serialPort->write(request2) == -1) {
        qDebug() << "Write failed (2):" << serialPort->errorString();
//        if (m_timer) m_timer->start(2000);
        return;
    }

    // 读取第二条响应
    QByteArray response2;
    if (serialPort->waitForReadyRead(1000)) {
        response2 = serialPort->readAll();
        while (serialPort->waitForReadyRead(100)) {
            response2 += serialPort->readAll();
        }
    } else {
        qDebug() << "Read timeout (2)";
//        if (m_timer) m_timer->start(2000);
        return;
    }

    /**************** 解析响应数据并更新UI ****************/

    // 解析第一条响应 (0x47-0x50) - 10个寄存器
    if (response1.size() >= 23) {  // 10寄存器×2 + 5字节头尾
        // 寄存器0x47: TVOC报警上限
        quint16 TVOC_UP = (static_cast<quint8>(response1[3]) << 8) | static_cast<quint8>(response1[4]);
        ui->PECY_UP->setText(QString::number(TVOC_UP/1000.0,'f',3));

        // 寄存器0x48: TVOC报警上限回差
        quint16 TVOC_UPDEFF = (static_cast<quint8>(response1[5]) << 8) | static_cast<quint8>(response1[6]);
        ui->PECY_UPDEFF->setText(QString::number(TVOC_UPDEFF/1000.0,'f',3));

        // 寄存器0x49: TVOC报警上限继电器
        quint16 TVOC_UPRELAY = (static_cast<quint8>(response1[7]) << 8) | static_cast<quint8>(response1[8]);
        ui->PECY_UPRELAY->setCurrentIndex(TVOC_UPRELAY);

        // 寄存器0x4A: TVOC报警下限
        quint16 TVOC_DOWN = (static_cast<quint8>(response1[9]) << 8) | static_cast<quint8>(response1[10]);
        ui->PECU_DOWN->setText(QString::number(TVOC_DOWN/1000.0,'f',3));

        // 寄存器0x4B: TVOC报警下限回差
        quint16 TVOC_DOWNDEFF = (static_cast<quint8>(response1[11]) << 8) | static_cast<quint8>(response1[12]);
        ui->PECU_DOWNDEFF->setText(QString::number(TVOC_DOWNDEFF/1000.0,'f',3));

        // 寄存器0x4C: TVOC报警下限继电器
        quint16 TVOC_DOWNRELAY = (static_cast<quint8>(response1[13]) << 8) | static_cast<quint8>(response1[14]);
        ui->PECU_DOWNRELAY->setCurrentIndex(TVOC_DOWNRELAY);

        // 寄存器0x4D: TVOC预警上限
        quint16 TVOC_UPWARNING = (static_cast<quint8>(response1[15]) << 8) | static_cast<quint8>(response1[16]);
        ui->PECY_UPWARNING->setText(QString::number(TVOC_UPWARNING/1000.0,'f',3));

        // 寄存器0x4E: TVOC预警上限开关
        quint16 TVOC_UPWARNING_EN = (static_cast<quint8>(response1[17]) << 8) | static_cast<quint8>(response1[18]);
        ui->PECY_UPWARNING_EN->setCurrentIndex(TVOC_UPWARNING_EN);

        // 寄存器0x4F: TVOC预警下限
        quint16 TVOC_DOWANWARNING = (static_cast<quint8>(response1[19]) << 8) | static_cast<quint8>(response1[20]);
        ui->PECU_DOWNWARNING->setText(QString::number(TVOC_DOWANWARNING/1000.0,'f',3));

        // 寄存器0x50: TVOC预警下限开关
        quint16 TVOC_DOWNWARNING_EN = (static_cast<quint8>(response1[21]) << 8) | static_cast<quint8>(response1[22]);
        ui->PECU_DOWNWARNING_EN->setCurrentIndex(TVOC_DOWNWARNING_EN);
    } else {
        qDebug() << "Invalid response1 length:" << response1.size();
    }

    // 解析第二条响应 (0x88-0x89) - 2个寄存器
    if (response2.size() >= 7) {  // 2寄存器×2 + 5字节头尾
        // 寄存器0x88: TVOC校准系数
        qint16 TVOCK = (static_cast<quint8>(response2[3]) << 8) | static_cast<quint8>(response2[4]);
        ui->PECU_K->setText(QString::number(TVOCK/10.0,'f',1));

        // 寄存器0x89: TVOC偏移修正
        quint16 TVOCB = (static_cast<quint8>(response2[5]) << 8) | static_cast<quint8>(response2[6]);
        ui->PECU_B->setText(QString::number(TVOCB/1000.0,'f',3));
    } else {
        qDebug() << "Invalid response2 length:" << response2.size();
    }

    // 恢复定时器（如果有）
//    if (m_timer) m_timer->start(2000);
}

void zg291pecu_para::on_pushButton_2_clicked()
{
    // 停止定时器（如果有）
    if (m_timer && m_timer->isActive()) {
        m_timer->stop();
    }

    // 检查串口状态
    if (!serialPort || !serialPort->isOpen()) {
        qDebug() << "Serial port not ready!";
//        if (m_timer) m_timer->start(2000);
        return;
    }

    /**************** 第一条指令：写入0x47-0x50寄存器 (10个寄存器) ****************/
    QByteArray request1;
    request1.append(static_cast<char>(0x00));     // 从机地址
    request1.append(static_cast<char>(0x10));     // 功能码(写多个寄存器)
    request1.append(static_cast<char>(0x00));     // 起始地址高字节
    request1.append(static_cast<char>(0x73));     // 起始地址低字节 (0x47)
    request1.append(static_cast<char>(0x00));     // 寄存器数高字节
    request1.append(static_cast<char>(0x0A));     // 寄存器数低字节 (10个寄存器)
    request1.append(static_cast<char>(0x14));     // 字节数 (10寄存器×2=20字节)

    // 添加寄存器值
    float tvoc_up=ui->PECY_UP->text().toFloat();
    short tvoc_upint=static_cast<short>(tvoc_up * 1000);
    request1.append(static_cast<char>(tvoc_upint >> 8));
    request1.append(static_cast<char>(tvoc_upint & 0xFF));

    float tvoc_updeff=ui->PECY_UPDEFF->text().toFloat();
    short tvoc_updeffint=static_cast<short>(tvoc_updeff * 1000);
    request1.append(static_cast<char>(tvoc_updeffint >> 8));
    request1.append(static_cast<char>(tvoc_updeffint & 0xFF));

    request1.append(static_cast<char>(ui->PECY_UPRELAY->currentIndex() >> 8));
    request1.append(static_cast<char>(ui->PECY_UPRELAY->currentIndex() & 0xFF));

    float tvoc_down=ui->PECU_DOWN->text().toFloat();
    short tvoc_downint=static_cast<short>(tvoc_down * 1000);
    request1.append(static_cast<char>(tvoc_downint >> 8));
    request1.append(static_cast<char>(tvoc_downint & 0xFF));

    float tvoc_downdeff=ui->PECU_DOWNDEFF->text().toFloat();
    short tvoc_downdeffint=static_cast<short>(tvoc_downdeff * 1000);
    request1.append(static_cast<char>(tvoc_downdeffint >> 8));
    request1.append(static_cast<char>(tvoc_downdeffint & 0xFF));

    request1.append(static_cast<char>(ui->PECU_DOWNRELAY->currentIndex() >> 8));
    request1.append(static_cast<char>(ui->PECU_DOWNRELAY->currentIndex() & 0xFF));

    float tvoc_upwarning=ui->PECY_UPWARNING->text().toFloat();
    short tvoc_upwarningint=static_cast<short>(tvoc_upwarning * 1000);
    request1.append(static_cast<char>(tvoc_upwarningint >> 8));
    request1.append(static_cast<char>(tvoc_upwarningint & 0xFF));

    request1.append(static_cast<char>(ui->PECY_UPWARNING_EN->currentIndex() >> 8));
    request1.append(static_cast<char>(ui->PECY_UPWARNING_EN->currentIndex() & 0xFF));

    float tvoc_downwarning=ui->PECU_DOWNWARNING->text().toFloat();
    short tvoc_downwarningint=static_cast<short>(tvoc_downwarning * 1000);
    request1.append(static_cast<char>(tvoc_downwarningint >> 8));
    request1.append(static_cast<char>(tvoc_downwarningint & 0xFF));

    request1.append(static_cast<char>(ui->PECU_DOWNWARNING_EN->currentIndex() >> 8));
    request1.append(static_cast<char>(ui->PECU_DOWNWARNING_EN->currentIndex() & 0xFF));

    // 计算并附加CRC
    quint16 crc1 = calculateCRC(request1);
    request1.append(static_cast<char>(crc1 & 0xFF));
    request1.append(static_cast<char>((crc1 >> 8) & 0xFF));

    // 发送第一条指令
    if (serialPort->write(request1) == -1) {
        qDebug() << "Write failed (1):" << serialPort->errorString();
//        if (m_timer) m_timer->start(2000);
        return;
    }

    // 读取第一条响应
    QByteArray response1;
    if (serialPort->waitForReadyRead(1000)) {
        response1 = serialPort->readAll();
        while (serialPort->waitForReadyRead(100)) {
            response1 += serialPort->readAll();
        }
    } else {
        qDebug() << "Write response timeout (1)";
//        if (m_timer) m_timer->start(2000);
        return;
    }

    /**************** 第二条指令：写入0x88-0x89寄存器 (2个寄存器) ****************/
    QByteArray request2;
    request2.append(static_cast<char>(0x00));     // 从机地址
    request2.append(static_cast<char>(0x10));     // 功能码(写多个寄存器)
    request2.append(static_cast<char>(0x00));     // 起始地址高字节
    request2.append(static_cast<char>(0x90));     // 起始地址低字节 (0x88)
    request2.append(static_cast<char>(0x00));     // 寄存器数高字节
    request2.append(static_cast<char>(0x02));     // 寄存器数低字节 (2个寄存器)
    request2.append(static_cast<char>(0x04));     // 字节数 (2寄存器×2=4字节)

    // 处理浮点数校准系数
    float TVOCK_float = ui->PECU_K->text().toFloat();
    short TVOCK_int = static_cast<short>(TVOCK_float * 10);

    request2.append(static_cast<char>(TVOCK_int >> 8));
    request2.append(static_cast<char>(TVOCK_int & 0xFF));

    float TVOCB_float = ui->PECU_B->text().toFloat();
    short TVOCB_int = static_cast<short>(TVOCB_float * 1000);
    request2.append(static_cast<char>(TVOCB_int >> 8));
    request2.append(static_cast<char>(TVOCB_int & 0xFF));

    // 计算并附加CRC
    quint16 crc2 = calculateCRC(request2);
    request2.append(static_cast<char>(crc2 & 0xFF));
    request2.append(static_cast<char>((crc2 >> 8) & 0xFF));

    // 发送第二条指令
    if (serialPort->write(request2) == -1) {
        qDebug() << "Write failed (2):" << serialPort->errorString();
//        if (m_timer) m_timer->start(2000);
        return;
    }

    // 读取第二条响应
    QByteArray response2;
    if (serialPort->waitForReadyRead(1000)) {
        response2 = serialPort->readAll();
        while (serialPort->waitForReadyRead(100)) {
            response2 += serialPort->readAll();
        }
    } else {
        qDebug() << "Write response timeout (2)";
//        if (m_timer) m_timer->start(2000);
        return;
    }

    // 恢复定时器（如果有）
//    if (m_timer) m_timer->start(2000);

    qDebug() << "TVOC Parameters set successfully";
}
